package com.kcs.fxmargin.action;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.kcs.common.utils.Constant;
import com.kcs.fxmargin.action.form.LoginActionForm;
import com.kcs.fxmargin.action.form.SetupRoleProfileActionForm;
import com.kcs.fxmargin.bo.SetupRoleProfileBO;
import com.kcs.fxmargin.service.SetupRoleProfileService;

public class SetupRoleProfileAction extends FXAction {
	private Logger log = Logger.getLogger(Constant.LOG_FX);
	private final String SPLITTER = "_";
   
	@Override
	public ActionForward process(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		SetupRoleProfileActionForm bean = null;
		SetupRoleProfileBO bo = null;
		SetupRoleProfileService svc = null;
		LoginActionForm userInfo = (LoginActionForm) request.getSession().getAttribute(Constant.LOGIN_DATA_SESSION);
		try{
			
			bean = (SetupRoleProfileActionForm)form;
			
			System.out.println("> userInfo: "+userInfo);
			System.out.println("> userId: "+userInfo.getUserId());
			
			bo = new SetupRoleProfileBO();
			svc = new SetupRoleProfileService();
			
			if(bean.getTranCode().equals("")){
				bo.setCreateBy(userInfo.getUserId());
				bo = svc.getFunctionList(bo);
				generateHTMLAndSetAttribute(bo.getFunctionList(),request);
				bean.setFunctionList(bo.getFunctionList());
			
			}else if(bean.getTranCode().equals("saveRoleProfile")){
				saveRoleProfile(bean,request);
				
			}else if(bean.getTranCode().equals("resetRoleProfile")){
				resetRoleProfile(bean,request);
			}
			
			
		}catch(Exception e){
			e.printStackTrace();
			request.setAttribute(Constant.ERR_ATTR, e.getMessage());
			
		}finally{
			if(bean != null){
				bean.setTranCode("");
			}
		}

		return mapping.findForward("setupRoleProfile");
	}

	private String generateSetupUserProfileHTML(List<SetupRoleProfileBO> functionList, HttpServletRequest request)throws Exception{
		String result = "<div name='divFunctionList' class='MarginTable'>";
		List<String> uniqueMenuIdList = null;
		List<String> uniqueRoleList = null;
		SetupRoleProfileBO bo = null;
		String menuName = null;
		int countFunction = 0;
		int checkBoxIndex = 0;
		
		if(functionList != null){
			uniqueMenuIdList = getUniqueMenuIdList(functionList);
			uniqueRoleList = getUniqueRoleList(functionList);
			
			System.out.println("> uniqueMenuIdList size = "+uniqueMenuIdList.size());
			System.out.println("> uniqueRoleList size = "+uniqueRoleList.size());
			
			//Header Row
			result += "<table width='100%'>"
					 +"<tr>"
			         +"<th>No.</th>"
			         +"<th>FUNCTION</th>";
			
			for(int i=0; i<uniqueRoleList.size(); i++){
				result += "<th>"+getRoleCodeFromRoleString(uniqueRoleList.get(i))+"</th>";
			}

			result += "</tr>";
				
			for(int i=0; i<uniqueMenuIdList.size(); i++){
				countFunction++;
				menuName = getMenuNameFromFunctionList(functionList, uniqueMenuIdList.get(i));
				
				result += "<tr>"
				         +"<td style='text-align:center;'>" +countFunction+ "</td>"
				         +"<td style='text-align:left;'>" +menuName+ "</td>";
				
				for(int j=0; j<uniqueRoleList.size(); j++){
					bo = getBOFromFunctionList(functionList, uniqueMenuIdList.get(i), getRoleIdFromRoleString(uniqueRoleList.get(j)));
					
					if(bo != null){
						result += "<td>"+getCheckboxHTML(bo.getAuthFlag(),checkBoxIndex)
						       + getHiddenElementsHTML(bo.getMenuId(), bo.getMenuName(), bo.getAuthId(), bo.getRoleId(), bo.getCode(),bo.getRowVersion())
						       + "</td>";
						checkBoxIndex++;
					}
				}
				
				result += "</tr>";
			}
			
			result += "</table>"
					 +"</br>"
					 +"<center><input type='button' class='button' name='btnSave' value='Save' onclick='saveRoleProfile();'/>&nbsp;<input type='reset' class='button' value='Reset'></center>";
			
		}else{
			request.setAttribute(Constant.ERR_ATTR, Constant.ERR_FUNCTION_LIST_EMPTY);
		}
		
		result += "</div>";
		
		return result;
	}
	
	private List<String> getUniqueMenuIdList(List<SetupRoleProfileBO> functionList)throws Exception{
		List<String> resultList = new ArrayList<String>();
		List<String> tempList = new ArrayList<String>();
		HashSet<String> hs = new HashSet<String>();
		SetupRoleProfileBO bo = null;
		String[] spr = null;
		
		//Get menuId
		for(int i=0; i<functionList.size(); i++){
			bo = functionList.get(i);
			hs.add(bo.getMenuId()+"_"+bo.getSeqShow());
		}

		//Insert unique menuId into tempList
		for(String s : hs){
			tempList.add(s);
		}
		
		//Sort
		Collections.sort(tempList, new Comparator<String>() {
			public int compare(String s1, String s2) {
				String[] ar1 = s1.split("_");
				String[] ar2 = s2.split("_");
				int n1 = Integer.parseInt(ar1[1]);
				int n2 = Integer.parseInt(ar2[1]);
				return (n1 > n2)?1:0;
			}
		});
		
		//Add to resultList
		for(int i=0; i<tempList.size(); i++){
			spr = tempList.get(i).split("_");
			resultList.add(spr[0]);
		}
		
		//--
		
		return resultList;
	}
	
	private List<String> getUniqueRoleList(List<SetupRoleProfileBO> functionList)throws Exception{
		List<String> resultList = new ArrayList<String>();
		HashSet<String> hs = new HashSet<String>();
		SetupRoleProfileBO bo = null;
		Object[] tmp = null;
		
		//Get roleId
		for(int i=0; i<functionList.size(); i++){
			bo = functionList.get(i);
			if(bo.getRoleId() != null && bo.getCode() != null){
				hs.add(bo.getRoleId()+SPLITTER+bo.getCode());
			}
		}
		
		//Insert unique roleId into resultList
		tmp = hs.toArray();
		for(int i=0; i<tmp.length; i++){
			resultList.add(tmp[i].toString());
		}
		//--
		
		//Sort
		Collections.sort(resultList);
		
		return resultList;
	}
	
	private String getRoleIdFromRoleString(String s)throws Exception{
		String[] sprt = s.split(SPLITTER);
		return sprt[0];
	}
	
	private String getRoleCodeFromRoleString(String s)throws Exception{
		String[] sprt = s.split(SPLITTER);
		return sprt[1];
	}
	
	private SetupRoleProfileBO getBOFromFunctionList(List<SetupRoleProfileBO> functionList, String menuId, String roleId)throws Exception{
		SetupRoleProfileBO result = null;
		
		if(functionList == null || menuId == null || roleId == null){
			return null;
		}
		
		for(int i=0; i<functionList.size(); i++){
			result = functionList.get(i);
		
			if(result.getMenuId() != null && result.getRoleId() != null){
				if(result.getMenuId().equals(menuId) && result.getRoleId().equals(roleId)){
					return result;
				}
			}
		}
		
		return result;
	}
	
	private String getMenuNameFromFunctionList(List<SetupRoleProfileBO> functionList, String menuId)throws Exception{
		SetupRoleProfileBO bo = null;
		
		for(int i=0; i<functionList.size(); i++){
			bo = functionList.get(i);
			if(bo.getMenuId().equals(menuId)){
				return bo.getMenuName();
			}
		}
		
		return null;
	}
	
	private String getCheckboxHTML(String flag, int checkBoxIndex)throws Exception{
		
		if(flag == null){
			return "";
		}
		
		return  "<input type='hidden' name='authFlagList' id='authFlagList_"+checkBoxIndex+"' value='"+(flag.equals("1")?"1":"0")+"'/>"
			   +"<input type='checkbox' name='cbAuthFlagList' id='cbAuthFlagList_"+checkBoxIndex+"' "+(flag.equals("1")?"checked":"")+" onclick='updateFlagValue(this);'></input>";
	}
	
	private String getHiddenElementsHTML(String menuId, String menuName, String authId, String roleId, String code,int rowVersion)throws Exception{
		if(menuId == null || menuName == null || authId == null || roleId == null || code == null){
			return "";
		}
		
		return "<input type='hidden' name='menuIdList' value='"+menuId+"'></input>"
			  +"<input type='hidden' name='menuNameList' value='"+menuName+"'></input>"
			  +"<input type='hidden' name='authIdList' value='"+authId+"'></input>"
			  +"<input type='hidden' name='roleIdList' value='"+roleId+"'></input>"
			  +"<input type='hidden' name='codeList' value='"+code+"'></input>"
		      +"<input type='hidden' name='rowVersionList' value='"+rowVersion+"'></input>";
	}
	
	private void saveRoleProfile(SetupRoleProfileActionForm bean, HttpServletRequest request)throws Exception{
		String[] menuId 	= bean.getMenuIdList();
		String[] menuName 	= bean.getMenuNameList();
		String[] authId 	= bean.getAuthIdList();
		String[] authFlag   = bean.getAuthFlagList();
		String[] roleId 	= bean.getRoleIdList();
		String[] code 		= bean.getCodeList();
		String[] rowVersions = bean.getRowVersionList();
		
		SetupRoleProfileBO oldBO = null;
		SetupRoleProfileBO newBO = null;
		SetupRoleProfileService svc = null;
		log.info("saveRoleProfile.start()");
		try{
			for(int i=0; i<authId.length; i++){
				newBO = new SetupRoleProfileBO();
				newBO.setMenuId(menuId[i]);
				newBO.setMenuName(menuName[i]);
				newBO.setAuthId(authId[i]);
				newBO.setAuthFlag(authFlag[i]);
				newBO.setRoleId(roleId[i]);
				newBO.setCode(code[i]);
				newBO.setRowVersion(Integer.parseInt(rowVersions[i]));
				oldBO = getBOFromFunctionList(bean.getFunctionList(),newBO.getMenuId(),newBO.getRoleId());
				if(oldBO != null){
					oldBO.setAuthFlag(newBO.getAuthFlag());
				}
		
			}
			LoginActionForm userInfo = (LoginActionForm) request.getSession().getAttribute(Constant.LOGIN_DATA_SESSION);
			log.debug("userInfo ="+userInfo.getUserId());
			newBO = new SetupRoleProfileBO();
			newBO.setFunctionList(bean.getFunctionList());
			newBO.setUpdateBy(userInfo.getUserId());
			svc = new SetupRoleProfileService();
			int res = svc.updateRoleProfile(newBO);
			log.debug("saveRoleProfile res ="+res);
			if(res > 0){
				request.setAttribute(Constant.ERR_ATTR, "Save Completed");
			}
			else{
				request.setAttribute(Constant.ERR_ATTR, "Save Fail");
			}
			log.info("res ="+res);
			bean.setFunctionList(svc.getFunctionList(newBO).getFunctionList());
			generateHTMLAndSetAttribute(bean.getFunctionList(), request);
		}
		catch(Exception e){
			request.setAttribute(Constant.ERR_ATTR, "Save Fail");
			log.error(e);
			throw e;
		}
	}
	
	private void resetRoleProfile(SetupRoleProfileActionForm bean, HttpServletRequest request)throws Exception{
		if(bean.getFunctionList() != null){
			generateHTMLAndSetAttribute(bean.getFunctionList(),request);
		}
	}
	
	private String generateHTMLAndSetAttribute(List<SetupRoleProfileBO> functionList, HttpServletRequest request)throws Exception{
		String html = generateSetupUserProfileHTML(functionList, request);
		setAttributeHTML(html,request);
		return html;
	}
	
	private void setAttributeHTML(String html, HttpServletRequest request)throws Exception{
		request.setAttribute(Constant.FUCTION_LIST_ATTR, html);
	}
	
}
